import { SYSTEM_NAME } from '@/constants';
import HeaderRightContent from '@/layouts/HeaderRightContent';
import WebscoketGlobalWrap from '@/layouts/WebscoketGlobalWrap';
import {
  queryAliyunOssUploadPresigned,
  queryCtyunOssUploadPresigned,
  queryDictsByDictTypeId,
  queryDictTypes,
  queryUploadFile,
  UPLOAD_FILE_API_PATH,
} from '@/services';
import { queryBackendEnums } from '@/services/core/GlobalService';
import { queryFrontMenuTree } from '@/services/system/menu/MenuService';
import { queryCurrentUser } from '@/services/system/user/UserService';
import { getAuthInfo, getAuthToken } from '@/utils/auth';
import { transformToMenuDataItems, transformToMenuNamepathSet } from '@/utils/menu';

import type { ProLayoutProps } from '@ant-design/pro-components';
import { ProLayout } from '@ant-design/pro-components';
import { history, Outlet, RequestConfig, RunTimeLayoutConfig } from '@umijs/max';
import { message } from 'antd';
import classNames from 'classnames';
import {
  BackendEnum,
  BackendEnumItemKeyValPair,
  BackendEnumsKeyValPair,
  BackendEnumsTypeKeyValPair,
  DEFAULT_LOGIN_PATH as LOGIN_PATH,
  useKeepAliveContext,
} from 'kf-web-library';

import queryString from 'query-string';
import React from 'react';
import { matchRoutes } from 'umi';
import defaultSettings from '../config/defaultSettings';
import { errorConfig } from './utils/request';
import { AppInitialState, appInitialStateImpl } from '@/AppInitialState';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';

/**
 * @name  全局初始化数据配置
 * 用于 Layout 用户信息和权限初始化
 * 更多信息见文档：https://next.umijs.org/docs/api/runtime-config#getinitialstate
 */
export async function getInitialState(): Promise<AppInitialState> {
  //获取当前登录用户信息函数
  const fetchUserInfo = async () => {
    try {
      const currentUserResp = await queryCurrentUser({
        skipErrorHandler: true,
      });
      return currentUserResp.data;
    } catch (error) {
      //如果未能获取, 就重定向到登录页面
      message.error('未登陆或登陆已过时，请重新登陆！');
      history.push(LOGIN_PATH);
    }
    return undefined;
  };

  //获取后端枚举定义
  //获取后端枚举定义
  const fetchBackendEnums = async () => {
    const backendEnumsResp = await queryBackendEnums();
    const backendEnumArray = backendEnumsResp.data;

    // 将 BackendEnum[] 转换为 BackendEnumsKeyValPair
    const ret: BackendEnumsKeyValPair = {};
    const typeRet: BackendEnumsTypeKeyValPair = {};
    backendEnumArray.forEach((item: BackendEnum) => {
      const opts = item.enums;
      const mappingResult: BackendEnumItemKeyValPair = {};
      opts.forEach((opt) => {
        mappingResult[opt.enumName] = opt;
      });
      ret[item.enumType] = mappingResult;
      typeRet[item.enumType] = item.enumTypeDesc;
    });
    return {
      enumDict: ret,
      enumTypeDict: typeRet,
    };
  };

  //获取展示菜单
  const fetchFrontMenus = async () => {
    const frontMenus = await queryFrontMenuTree();
    return frontMenus.data;
  };

  //获取登录后需要fetch的信息 (用户信息, 后端枚举, 展示菜单定义)
  const fetchLoggedInfo = async () => {
    const currentUserInfo = await fetchUserInfo();
    if (!currentUserInfo) {
      return undefined;
    }
    const loggedAddts = await Promise.all([fetchBackendEnums(), fetchFrontMenus()]);
    return {
      currentUserInfo,
      currentAuthInfo: getAuthInfo(),
      backendEnum: {
        enumDict: loggedAddts[0].enumDict,
        enumTypeDict: loggedAddts[0].enumTypeDict,
      },
      frontMenus: loggedAddts[1],
    };
  };

  let loggedInfo: any = undefined;
  // 如果不是登录页面才执行
  if (window.location.pathname !== LOGIN_PATH) {
    loggedInfo = await fetchLoggedInfo();
  }
  return {
    queryDictsByDictTypeId: queryDictsByDictTypeId,
    getAuthToken: getAuthToken,
    uploadConfig: {
      uploadFileApiPath: UPLOAD_FILE_API_PATH,
      queryUploadFile: queryUploadFile,
      queryAliyunOssUploadPresigned: queryAliyunOssUploadPresigned,
      queryCtyunOssUploadPresigned: queryCtyunOssUploadPresigned,
    },
    fetchUserInfo,
    fetchBackendEnums,
    fetchFrontMenus,
    fetchLoggedInfo,
    ...appInitialStateImpl,
    backendDict: {
      queryDictsByDictTypeId,
      queryDictTypes,
    },
    settings: defaultSettings,
    ...loggedInfo,
  };
}

/**
 *  内容区多tabs支持的 路由path 和 tab的名称 的映射.
 */
export const tabsLayout = ({ initialState, router }) => {
  const local = transformToMenuNamepathSet(initialState?.frontMenus || []);
  const ret = {
    local: {
      ...router.local,
      ...local,
    },
    icon: router.icon,
  }
  return ret;
};

/**
 * @name 主页面布局
 * ProLayout - 高级布局
 * @doc https://procomponents.ant.design/components/layout
 */
const CustomMenuItemDom = ({ item, defaultDom, baseMenuProps }) => {
  const { keepElements } = useKeepAliveContext() || {};
  if (item.path) {
    const menuPathname = new URL(item.path!, window.location.origin).pathname;
    return <a onClick={() => history.push(`${item.path}${keepElements?.current[menuPathname]?.search || ''}`)}>{defaultDom}</a>;
  } else {
    return defaultDom;
  }
};
export const layout: RunTimeLayoutConfig = ({ initialState, setInitialState }) => {
  const { fixedHeader = true, ...initialStateSetting } = { ...initialState?.settings };
  return {
    fixedHeader: false,
    ...initialStateSetting,
    disableMobile: true,
    className: 'kf-basic-layout',
    logo: null,
    siderWidth: 210,
    avatarProps: false,
    rightContentRender: () => <></>,
    token: {
      bgLayout: '#EEF1F6',
      colorBgAppListIconHover: 'rgba(0,0,0,0.06)',
      colorTextAppListIconHover: 'rgba(255,255,255,0.95)',
      colorTextAppListIcon: 'rgba(255,255,255,0.85)',
      header: {
        colorBgHeader: '#ffffff',
        heightLayoutHeader: 64,
      },
      sider: {
        colorBgCollapsedButton: '#fff',
        colorTextCollapsedButtonHover: 'rgba(0,0,0,0.65)',
        colorTextCollapsedButton: 'rgba(0,0,0,0.45)',
        colorMenuBackground: '#232E51',
        colorBgMenuItemCollapsedHover: 'rgba(0,0,0,0.06)',
        colorBgMenuItemCollapsedSelected: 'rgba(0,0,0,0.15)',
        colorMenuItemDivider: 'transparent',
        colorBgMenuItemHover: 'rgba(0,0,0,0.06)',
        colorBgMenuItemSelected: 'rgba(0,0,0,0.15)',
        colorTextMenuSelected: '#4D76F3',
        colorTextMenu: 'rgba(255,255,255,0.75)',
        colorTextMenuSecondary: 'rgba(255,255,255,0.65)',
        colorTextMenuTitle: '#F0F4FB',
        colorTextMenuActive: 'rgba(255,255,255,0.95)',
        colorTextMenuItemHover: 'rgba(255,255,255,0.95)',
        colorTextSubMenuSelected: '#fff',
      },
      pageContainer: {
        marginBlockPageContainerContent: 0,
        marginInlinePageContainerContent: 0,
      },
    },
    menuItemRender: (item, defaultDom, baseMenuProps) => {
      return <CustomMenuItemDom item={item} defaultDom={defaultDom} baseMenuProps={baseMenuProps} />;
    },
    menu: {
      locale: false,
      request: async () => {
        return transformToMenuDataItems(initialState?.frontMenus || [], initialState?.currentAuthInfo);
      },
    },
    childrenRender: (children: JSX.Element, proLayoutProps: ProLayoutProps) => {
      return (
        <WebscoketGlobalWrap>
          <ProLayout
            className={classNames('content-pro-layout', { 'content-fixed-header-pro-layout': fixedHeader })}
            disableMobile={true}
            title={`${SYSTEM_NAME}`}
            token={{
              header: {
                colorHeaderTitle: '#252E4F',
              },
            }}
            logo={null}
            layout={'top'}
            fixedHeader={fixedHeader}
            menuRender={false}
            avatarProps={false}
            //@ts-ignore
            rightContentRender={(p) => <HeaderRightContent />}
          >
            <Outlet />
          </ProLayout>
        </WebscoketGlobalWrap>
      );
    },
  } as any;
};

export const onRouteChange = (routeChangeProps: any) => {
  const { clientRoutes, location } = routeChangeProps;
  const route = matchRoutes(clientRoutes, location.pathname)?.pop()?.route as any;
  if (route) {
    document.title = (route.title || route.name || 'Unknow') + ' - ' + defaultSettings.title;
  }
};

/**
 * @name request 配置，可以配置错误处理
 * 它基于 axios 和 ahooks 的 useRequest 提供了一套统一的网络请求和错误处理方案。
 * @doc https://umijs.org/docs/max/request#配置
 */

export const request: () => RequestConfig = () => {
  return {
    /**
     * Umi@4 请求基于 axios，默认是带括号 [] 的形式序列化
     * 例: a: [1,2,3]  默认序列化形式 a[]=1&a[]=2&a[]=3
     * 这里将其变更为 a=1&a=2&a=3 的形式
     */
    paramsSerializer: (params) => {
      return queryString.stringify(params);
    },
    baseURL: REQUEST_BASE_URL,
    ...errorConfig,
  };
};

export function rootContainer(container: React.ReactNode) {
  dayjs.locale('zh-cn');
  return container;
}
